On linux:
$ sudo apt install git
On Mac/Windows probably better to use conda
/ anaconda
. Mac system version is outdated.
At the very minimum:
$ git config --global user.name "Vasya Pupkin"
$ git config --global user.email "vasya.pupkin@russianhackers.org"
probably makes sense to set the default editor for commit messages:
$ git config --global core.editor vim
Initialize:
$ git init
$ ls -lah
Note .git
directory. That's where all the magic lives.
Add stuff to the repo.
$ git add .
Can be more specific here (git add *.py
).
Let's look at the state of the repository.
$ git status
And now commit the changes.
$ git commit -a -m "Initial commit"
Every file in a repository can be in one of three states: commited, staged, modified.
Working dir Staging Repository
<--------------------- checkout ----------------------|
|------ stage (add) ------->
|--------- commit --------->
|
All the above repo creation steps can be done on github.com
.
When creating a new repo make sure to include LICENSE otherwise the default copyright will apply which means "all rights reserved".
Then the remote repo (on any server) can be copied via clone
command:
$ git clone https://github.com/eco32i/biodata.git
This will create a new directory biodata
, set up a new git
repo in it (.git
directory), point to the remote address and retrieve the latest version of the code from the remote.
What happens to a file in the repo:
git
flags it "modified"Use status
command to check the state of your repo:
$ git status
Aside: HEAD
always points to the latest commit (unless it's detached).
Push your changes to the remote:
$ git push origin master
Repo can have as many remotes as one wishes:
$ git remote -v
To add a remote:
$ git remote add upstream https://github.com/vasyapupkin/project
Now to fetch the content of a remote, use fetch
command:
$ git fetch [remote-name]
Note that this will not change your working directory (won't do merge).
To push your changes to a remote:
$ git push [remote-name] [branch-name]
If you want to checkout or pull a remote and have uncommitted changes:
$ git stash
This will temporarily hide your changes. To restpore them:
$ git stash apply
Say, you forgot to include a new file into your last commit:
$ git commit --amend
Unstaging file:
$ git reset HEAD index.ipynb
Unstaged changes after reset:
M index.html
Undo a commit:
$ git revert HEAD
This will only work for the last commit.
To switch to a different commit:
First identify the commit you want to revert to
$ git log
To temporarily switch to a commit (pro-tip: use Tab-completion)
$ git checkout [commit-hash]
Same but checkout old commit as a branch
$ git checkout -b old-state [commit-hash]
To toss everything since the old commit
$ git reset --hard [commit-hash]
If you want to keep your work
$ git stash
$ git reset --hard [commit-hash]
$ git stash pop
Undo published commits: you probably don't want to reset the branch, since that's effectively rewriting history. In that case, you could revert the commits. With Git, revert has a very specific meaning: create a commit with the reverse patch to cancel it out. This way you don't rewrite any history.
# This will create three separate revert commits:
$ git revert a867b4af 25eee4ca 0766c053
# It also takes ranges. This will revert the last two commits:
$ git revert HEAD~2..HEAD
# Then commit. Be sure and write a good message describing what you just did
$ git commit
Branches are cheap and easy. Always do branches! They are also integral part of github workflow
.
To create and checkout a new branch:
$ git checkout -b test
To list all branches:
$ git branch
Generally all development should happen in branches, master
branch should be for the stable production code.
The HEAD
moves to the most recent commit in the branch being merged in. Only works if there is no divergent work in that branch.
$ git checkout master
$ git merge test
You can explicitly disable Fast-forward. In that case a new commit object will be created.
$ git merge test --no-ff
If the branches have diverged the three-way merge is done: a new snapshot created from the most recent commits in each branch and a new commit that points to it.
If automatic three-way merge fails, the conflicts must be resolved manually. Use status
command to identify files that need fixing:
$ git status
# On branch master
# Unmerged paths:
# (use “git add/rm …” as appropriate to mark resolution)
#
# both modified: index.html
#
$ git diff master test
Then edit those files (they will have conflict markers in places that failed to merge):
My name is
<<<<<<< HEAD
Jane
=======
Mary
>>>>>>> branch-test
Edit each of the conflicting files, then use git add <filename>
to mark them as resolved
Use case: you created a topic branch and started working on it. In the meantime others updated master. You want to stay on your topic branch and keep working on it but you want it to incorporate latest changes from master.
$ git checkout test
... do some work ...
$ git fetch master
$ git rebase master
This rewrites the history by replaying all commits from one branch (master) on another (test).
In [ ]: